package com.eningqu.aipen.ui.vedio;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.PixelFormat;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceManager;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.PixelCopy;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.widget.FrameLayout;

import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;

import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.ScreenUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.eningqu.aipen.demo.PenCtrlSdkManager;
import com.eningqu.aipen.demo.R;
import com.eningqu.aipen.demo.common.Const;
import com.eningqu.aipen.demo.common.HttpUtils;
import com.eningqu.aipen.demo.databinding.ActivityNoteBinding;
import com.eningqu.aipen.demo.listener.TouchListener;
import com.eningqu.aipen.demo.view.CanvasDrawView;
import com.eningqu.aipen.demo.view.CanvasFrame;
import com.eningqu.aipen.sdk.bean.DotType;
import com.eningqu.aipen.sdk.bean.NQDot;
import com.eningqu.aipen.sdk.comm.ConnectState;
import com.eningqu.aipen.sdk.comm.utils.BytesConvert;
import com.eningqu.aipen.sdk.listener.PenDotListener;
import com.eningqu.aipen.sdk.listener.PenOfflineDataListener;
import com.eningqu.aipen.ui.base.BaseActivity;
import com.eningqu.aipen.ui.home.book.FormActivity;
import com.kongzue.dialogx.dialogs.FullScreenDialog;
import com.kongzue.dialogx.dialogs.PopTip;
import com.kongzue.dialogx.interfaces.OnBindView;

import java.util.LinkedHashMap;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * Package:com.eningqu.aipen.ui.vedio
 * Author:starr
 * Time:11/27/2023 7:57 PM
 * Description:
 */
public class NoteActivity extends BaseActivity<ActivityNoteBinding> {

    SendThread sendThread;//实时转换字迹的线程
    private static Integer blId;
    private CanvasFrame mCurCanvasFrame;//自定义画布
    private CanvasDrawView mCurDrawView;

    /**
     * 笔画粗细
     */
    final private int THIN = 2;
    final private int NORMAL = 4;
    final private int THICK = 6;

    /**
     * 笔画颜色
     */

    final private int BLACK = 1;
    final private int RED = 2;
    final private int GREEN = 3;
    final private int BLUE = 4;

    private final StringBuilder mDotsSb = new StringBuilder();
    private final float pageWHRatio = (float) 148 / 211;//纸张宽高比，默认a4

    private String mMac;//网卡mac地址
    SharedPreferences pref = null;

    private long mOfflineDataDots = 0;//离线数据点数量


    @SuppressLint("HandlerLeak")
    private final Handler mHandler = new Handler() {
        @SuppressLint({"HandlerLeak", "SetTextI18n"})
        @Override

        //Handler events that received from UART service
        public void handleMessage(Message msg) {
            if (msg.what == 1) {
            } else if (msg.what == 2) {
            } else if (msg.what == 3) {
                mBinding.tvPage.setText("Page:" + msg.arg1);
            } else if (msg.what == 4) {
                //跳转界面

            }
        }
    };


    public static void startAction(Context context, Bundle bundle) {
        Intent intent = new Intent(context, NoteActivity.class);
        blId = bundle.getInt("blId");
        context.startActivity(intent);
    }

    @Override
    protected int getLayoutId() {
        return R.layout.activity_note;
    }

    @Override
    protected void initView() {
        getWindow().setFormat(PixelFormat.TRANSLUCENT);
        //固定竖屏
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
        //屏幕常亮
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        pref = PreferenceManager.getDefaultSharedPreferences(getContext());
        mCurCanvasFrame = new CanvasFrame(getContext());
        mCurDrawView = mCurCanvasFrame.bDrawl;
        //初始化画板
        initDrawBroad(mBinding.flDrawBoard, mCurCanvasFrame);
        //获取网卡mac，也可以用其他唯一值来替代
        mMac = BytesConvert.bcdToString(HttpUtils.getMacFromHardware());
        if (sendThread == null) {
            sendThread = new SendThread(mMac, mCurDrawView, mHandler);
        }
        sendThread.setDaemon(true);
        sendThread.start();
        //设置笔的监听
        setListener();
    }

    /**
     * 初始化画板
     */
    private void initDrawBroad(@NonNull final FrameLayout frameLayout, @NonNull final CanvasFrame canvasFrame) {

        if (canvasFrame.initDrawBroad) {
            LogUtils.d("已装载画板");
            return;
        }

        LogUtils.d("装载画板");

        frameLayout.post(new Runnable() {
            public void run() {


                int width = ScreenUtils.getScreenWidth();
                int height = (int) ((float) ScreenUtils.getScreenWidth() / pageWHRatio);

                FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(width, height);
                layoutParams.width = ScreenUtils.getScreenWidth();

                canvasFrame.setLayoutParams(layoutParams);

                final CanvasDrawView drawView = canvasFrame.bDrawl;
                if (null != drawView) {
                    drawView.setZOrderOnTop(true); // 在最顶层，会遮挡一切view
                    drawView.setZOrderMediaOverlay(true);// 如已绘制SurfaceView则在surfaceView上一层绘制。
                    drawView.setDrawing(true);
                }

                canvasFrame.getViewTreeObserver().addOnGlobalLayoutListener(
                        new ViewTreeObserver.OnGlobalLayoutListener() {
                            @SuppressLint("ClickableViewAccessibility")
                            @Override
                            public void onGlobalLayout() {
                                LogUtils.d("onGlobalLayout 设置触摸监听");
                                canvasFrame.getViewTreeObserver().removeOnGlobalLayoutListener(this);

                                frameLayout.setOnTouchListener(new TouchListener(canvasFrame, frameLayout.getWidth(),
                                        frameLayout.getHeight(), canvasFrame.getMeasuredWidth(), canvasFrame.getMeasuredHeight()));

                                //设置笔默认的颜色和大小
                                setDefaultPenSizeAndColour();

                                canvasFrame.initDrawBroad = true;
                            }
                        });

                frameLayout.removeAllViews();
                frameLayout.addView(canvasFrame);
            }
        });
    }

    /**
     * 设置笔默认的颜色和大小
     */
    private void setDefaultPenSizeAndColour() {
        LogUtils.d("设置笔默认的颜色和大小");
        //获取缓存的笔画粗细,默认THIN
        int thickness = pref.getInt(Const.Pref.KEY_THICKNESS, THIN);
        Message message = Message.obtain();
        message.what = 1;
        switch (thickness) {
            case THIN:
                message.arg1 = 1;
                break;
            case NORMAL:
                message.arg1 = 2;
                break;
            case THICK:
                message.arg1 = 3;
                break;
        }

        //获取缓存的笔画颜色,默认BLACK
        int color = pref.getInt(Const.Pref.KEY_COLOR, BLACK);
        switch (color) {
            case BLACK:
                message.arg2 = 1;
                break;
            case RED:
                message.arg2 = 2;
                break;
            case GREEN:
                message.arg2 = 3;
                break;
            case BLUE:
                message.arg2 = 4;
                break;
        }
        mHandler.sendMessage(message);
    }

    @Override
    protected void initData() {
        mBinding.setClick(new WriteClick());
    }

    @Override
    protected void async() {

    }

    private void setListener() {
        //设置实时书写点接收监听
        PenCtrlSdkManager.getInstance().setDotListener(penDotListener);
        //监听离线同步数据
        PenCtrlSdkManager.getInstance().setPenOfflineDataListener(offlineDataListener);
    }

    /**
     * 存放点的信息
     */
    private static Queue<NQDot> nqDotQueue = new ConcurrentLinkedQueue<>();//保存当前操作的页面的点的信息
    private static final LinkedHashMap<Integer, Queue<NQDot>> nqMap = new LinkedHashMap<>();//存放多个页面的笔迹，键为页面

    /**
     * 静态内部类，用于实时书写的线程
     */
    private static class SendThread extends Thread {
        //共享资源
        private final Object lock = new Object();

        private final String mac;
        private final CanvasDrawView canvasDrawView;
        private int page = -1;
        private final Handler handler;

        public SendThread(String mac, CanvasDrawView canvasDrawView, Handler handler) {
            this.mac = mac;
            this.canvasDrawView = canvasDrawView;
            this.handler = handler;
        }

        void resumeThread() {
            synchronized (lock) {
                lock.notify();
            }
        }

        void onPause() {
            synchronized (lock) {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

        @Override
        public void run() {
            while (true) {
                while (!nqDotQueue.isEmpty()) {
                    NQDot nqDot = nqDotQueue.poll();
                    LogUtils.d("本地SDK返回: type=" + nqDot.type + "， dot.x=" + nqDot.x + " dot.y=" + nqDot.y
                            + ", page=" + nqDot.page + "，bookNum=" + nqDot.bookNum
                            + ", Width=" + nqDot.book_width + ", Height=" + nqDot.book_height);

                    if (page == -1) {//第一次更新页面信息
                        page = nqDot.page;
                    } else {
                        if (page != nqDot.page) {//点阵笔迹携带的页面信息与界面展示的界面信息不一样
                            Message message = new Message();
                            page = nqDot.page;
                            message.what = 3;
                            message.arg1 = page;
                            handler.sendMessage(message);
                            canvasDrawView.cleanCanvas();//更换页面，清空页面
                            continue;
                        }
                    }
                    canvasDrawView.addDot(mac, nqDot);
                }
                onPause();
            }
        }
    }

    /**
     * 实时书写点监听
     */
    PenDotListener penDotListener = new PenDotListener() {
        @SuppressLint("SetTextI18n")
        @Override
        public void onReceiveDot(final NQDot nqDot) {

            LogUtils.d("本地SDK返回: type=" + nqDot.type + "， dot.x=" + nqDot.x + " dot.y=" + nqDot.y
                    + ", page=" + nqDot.page + "，bookNum=" + nqDot.bookNum
                    + ", Width=" + nqDot.book_width + ", Height=" + nqDot.book_height);

            if (mDotsSb.length() > 4096) {
                //避免数据太多，及时清理
                mDotsSb.delete(0, 1024);
            }

            runOnUiThread(() -> {
                mBinding.tvPage.setText("Page:" + nqDot.page);
                mCurDrawView.addDot(mMac, nqDot);
            });

            if (nqDot.type == DotType.PEN_ACTION_DOWN) {
                //按下笔
                mDotsSb.append("(").append(nqDot.x).append(",").append(nqDot.y).append(")").append("  Down\n");
            } else if (nqDot.type == DotType.PEN_ACTION_MOVE) {
                //移动笔
                mDotsSb.append("(").append(nqDot.x).append(",").append(nqDot.y).append(")").append("  Move\n");
            } else if (nqDot.type == DotType.PEN_ACTION_UP) {
                //抬起笔
                mDotsSb.append("(").append(nqDot.x).append(",").append(nqDot.y).append(")").append("  Up\n");
//                mnPreXvalue = 0;
            }

            nqDotQueue = nqMap.getOrDefault(nqDot.page, new ConcurrentLinkedQueue<>());
            nqDotQueue.add(nqDot);
            nqMap.put(nqDot.page, nqDotQueue);
            LogUtils.d("当前页面：" + nqDot.page + " 当前nqDotQueue：" + nqDotQueue);

            sendThread.resumeThread();
        }

        @Override
        public void onError(int error, String message) {
            ToastUtils.showLong("异常信息: Msg=" + message + "， error=" + error);
        }
    };


    /**
     * 离线数据监听
     */
    PenOfflineDataListener offlineDataListener = new PenOfflineDataListener() {
        @Override
        public void offlineDataSyncStart(long l) {
            ToastUtils.showShort("开始同步离线数据 Len=" + l + " byte");
        }

        @Override
        public void offlineDataSyncStop() {
            mBinding.offlinedata.postDelayed(new Runnable() {
                @Override
                public void run() {
                    PenCtrlSdkManager.getInstance().requestDeleteOfflineData();
                }
            }, 2000);
            ToastUtils.showShort("同步完成");
        }

        @Override
        public void offlineDataDidReceivePenData(final NQDot nqDot) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
//                        LogUtils.d("离线数据本地SDK返回: type=" + nqDot.type + "， dot.x=" + nqDot.x + " dot.y=" + nqDot.y
//                                + ", page=" + nqDot.page + "，bookNum=" + nqDot.bookNum
//                                + ", Width=" + nqDot.book_width + ", Height=" + nqDot.book_height);
                    mCurDrawView.addDot(mMac, nqDot);
                    if (nqDot.type == DotType.PEN_ACTION_DOWN) {
                        mBinding.tvPage.setText("Page:" + nqDot.page);
                    }
                }
            });
        }

        @Override
        public void offlineDataDel() {
            ToastUtils.showShort("成功删除离线数据");
        }

        @Override
        public void offlineDataLength(long l) {
            ToastUtils.showShort("离线数据数量:" + l);
            mOfflineDataDots = l;
        }

        @Override
        public void onOffLineCurrentDataLength(long l) {

        }

    };


    /**
     * 点击事件
     * 切换笔迹大小
     * 切换笔迹颜色
     */
    @SuppressWarnings("all")
    public class WriteClick {
        public void penSizeSmall(View view) {
            mBinding.includePenSize.ivPenSizeThin.setBackgroundResource(R.drawable.shape_color_bg_white);
            mBinding.includePenSize.ivPenSizeMid.setBackground(null);
            mBinding.includePenSize.ivPenSizeThick.setBackground(null);
            mCurCanvasFrame.bDrawl.setSize(THIN);
            pref.edit().putInt(Const.Pref.KEY_THICKNESS, THIN).commit();
        }

        public void penSizeMid(View view) {
            mBinding.includePenSize.ivPenSizeThin.setBackground(null);
            mBinding.includePenSize.ivPenSizeMid.setBackgroundResource(R.drawable.shape_color_bg_white);
            mBinding.includePenSize.ivPenSizeThick.setBackground(null);
            mCurCanvasFrame.bDrawl.setSize(NORMAL);
            pref.edit().putInt(Const.Pref.KEY_THICKNESS, NORMAL).commit();
        }

        public void penSizeThick(View view) {
            mBinding.includePenSize.ivPenSizeThin.setBackground(null);
            mBinding.includePenSize.ivPenSizeMid.setBackground(null);
            mBinding.includePenSize.ivPenSizeThick.setBackgroundResource(R.drawable.shape_color_bg_white);
            mCurCanvasFrame.bDrawl.setSize(THICK);
            pref.edit().putInt(Const.Pref.KEY_THICKNESS, THICK).commit();
        }

        public void penColorBlack(View view) {
            mBinding.includePenColor.ivPenColorBlack.setBackgroundResource(R.drawable.shape_color_bg_white);
            mBinding.includePenColor.ivPenColorRed.setBackground(null);
            mBinding.includePenColor.ivPenColorGreen.setBackground(null);
            mBinding.includePenColor.ivPenColorBlue.setBackground(null);

            mCurCanvasFrame.bDrawl.setColor(ContextCompat.getColor(getContext(), R.color.color_000000));
            pref.edit().putInt(Const.Pref.KEY_COLOR, BLACK).commit();
        }

        //red
        public void penColorRed(View view) {
            mBinding.includePenColor.ivPenColorRed.setBackgroundResource(R.drawable.shape_color_bg_white);
            mBinding.includePenColor.ivPenColorBlack.setBackground(null);
            mBinding.includePenColor.ivPenColorGreen.setBackground(null);
            mBinding.includePenColor.ivPenColorBlue.setBackground(null);

            mCurCanvasFrame.bDrawl.setColor(ContextCompat.getColor(getContext(), R.color.color_E60012));
            pref.edit().putInt(Const.Pref.KEY_COLOR, BLACK).commit();
        }

        //green
        public void penColorGreen(View view) {
            mBinding.includePenColor.ivPenColorGreen.setBackgroundResource(R.drawable.shape_color_bg_white);
            mBinding.includePenColor.ivPenColorRed.setBackground(null);
            mBinding.includePenColor.ivPenColorBlack.setBackground(null);
            mBinding.includePenColor.ivPenColorBlue.setBackground(null);

            mCurCanvasFrame.bDrawl.setColor(ContextCompat.getColor(getContext(), R.color.color_45D151));
        }

        //blue
        public void penColorBlue(View view) {
            mBinding.includePenColor.ivPenColorBlue.setBackgroundResource(R.drawable.shape_color_bg_white);
            mBinding.includePenColor.ivPenColorRed.setBackground(null);
            mBinding.includePenColor.ivPenColorGreen.setBackground(null);
            mBinding.includePenColor.ivPenColorBlack.setBackground(null);

            mCurCanvasFrame.bDrawl.setColor(ContextCompat.getColor(getContext(), R.color.color_0D7993));
        }

        //离线数据
        public void penOfflineData(View view) {
            //请求离线数据
            PopTip.tip("正在请求离线数据");
            if (PenCtrlSdkManager.getInstance().getConnState() == ConnectState.CONN_STATE_CONNECTED) {
                PenCtrlSdkManager.getInstance().requestOfflineDataWithRange(0, (int) mOfflineDataDots);
            }
        }

        //ai智能手写体识别
        public void penAiCognize(View view) {
            PopTip.tip("识别手写体");
        }

        //辅助断针
        public void aiHelp(View view) {
            PopTip.tip("上传笔记");

        }

    }

    /**
     * 获取bitmap
     *
     * @param view
     * @return
     */
    private Bitmap getBitmap(SurfaceView view) {
        WindowManager manager = getWindowManager();
        DisplayMetrics metrics = new DisplayMetrics();
        manager.getDefaultDisplay().getMetrics(metrics);
        int width = metrics.widthPixels;
        int height = metrics.heightPixels;
        int measureWidth = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY);
        int measureHeight = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.AT_MOST);
        view.measure(measureWidth, measureHeight);
        view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
        Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
        final Canvas canvas = new Canvas(bitmap);
        view.draw(canvas);
//        bitmap=ScreenUtils.screenShot(this);
        return bitmap;

    }

    //获取到SurfaceView上的内容
    Bitmap mScreenBitmap = null;

    public Bitmap screenshot(SurfaceView view) {

        //需要截取的长和宽
        int outWidth = view.getWidth();
        int outHeight = view.getHeight();

        CanvasDrawView myView = (CanvasDrawView) view;
//        myView.setBackImage(BitmapFactory.decodeResource(getResources(),R.drawable.bg_word_null));

        mScreenBitmap = Bitmap.createBitmap(outWidth, outHeight, Bitmap.Config.ARGB_8888);
        PixelCopy.request(myView, mScreenBitmap, new PixelCopy.OnPixelCopyFinishedListener() {
            @Override
            public void onPixelCopyFinished(int copyResult) {
                if (PixelCopy.SUCCESS == copyResult) {
                    Log.i("gyx", "SUCCESS ");
                } else {
                    Log.i("gyx", "FAILED");
                    // onErrorCallback()
                }
            }
        }, new Handler());

        return mScreenBitmap;
    }

}
